package controllers;

import models.*;
import play.cache.Cache;

import java.util.*;

/**
 * @author Javier Gutierrez <bichocj@gmail.com>
 */
public class Security extends Secure.Security {


    /**
     * @param username
     * @param password
     * @should authenticate by username and password
     * @should get if the user is superadmin
     */
    static boolean authenticate(String username, String password) {
        if (session.get("username") != null) {
            return true;
        } else {
            Person persona = Person.findByUserAndPassword(username, password);
            if (persona != null) {
                session.put("username", persona.email);
                session.put("name", persona.name);
//                session.put("id", persona.id);
                if (persona.isSuperAdmin) {
                    session.put("perfil", Profile.SUPERADMIN);
                }
                return true;
            }
            return false;
        }
    }


    static boolean check(String profile) {

        String _profile = session.get("perfil");
        if (_profile != null) {
            if (_profile.equals("SUPERADMIN")) {
                //all permitions for superadmin
                return true;
            }
        }

        if (profile.equals(_profile)) {
            //TODO maybe it would never arrive here
            return true;
        }
        // verify a profile in an Event like jinis2011-Admin
        if (profile.contains("-")) {
            String event_nick = profile.substring(0, profile.indexOf('-'));
            _profile = profile.substring(profile.indexOf('-') + 1);
            return _profile.equals(session.get("perfil-" + event_nick));
        }

        String username = session.get("username");
//        if (username == null) {
//            return false;
//        }

        //for tasks on an event
        if (profile.contains("|")) {
            String task = profile.substring(0, profile.indexOf('|'));
            String event_nick = profile.substring(profile.indexOf('|') + 1);

            Set tasks = Cache.get(username + event_nick + "tasks", Set.class);
            if (tasks == null) {
                Event event = Event.getByNick(event_nick);
                Person person = Person.find("byEmail", username).first();
                List<Inscription> fetch = Inscription.find("byEventAndPersonDocument.person", event, person).fetch();
                if (fetch.size() == 0) {
                    tasks = new HashSet();
                } else {
                    Inscription inscription = fetch.get(0);
                    tasks = inscription.profile.tasks;
                    session.put("perfil-" + event_nick, inscription.profile.description);
                }

                Cache.set(username + event_nick + "tasks", tasks);

                List events_nick = Cache.get(username + "events_nicks", List.class);
                if (events_nick == null) {
                    events_nick = new ArrayList<String>();
                }
                events_nick.add(event_nick);
                Cache.set(username + "events_nicks", events_nick);

                return (fetch.size() == 0) ? false : true;
            }

            for (Iterator iterator = tasks.iterator(); iterator.hasNext(); ) {
                Task next = (Task) iterator.next();
                if (next.description.equals(task)) {
                    return true;
                }
            }
        }

        return false;
    }

    static void onDisconnect() {
        String username = session.get("username");
        List events_nick = Cache.get(username + "events_nicks", List.class);
        if (events_nick != null) {
            for (Iterator<String> iterator = events_nick.iterator(); iterator.hasNext(); ) {
                Cache.delete(username + iterator.next() + "tasks");
            }
        }
        Cache.delete(username + "events_nicks");
        session.clear();
    }

    static void onDisconnected() {
        String referer = request.headers.get("referer").value();
        if (referer.contains("/event/")) {
            referer = referer.substring(referer.lastIndexOf("/event/") + "/event/".length());
            if (referer.contains("/")) {
                referer = referer.substring(0, referer.indexOf("/"));
            }
            EventPageController.show(referer);
        } else {
            Application.index();
        }
    }

    public static void logout() {
        onDisconnect();
        session.clear();
        response.removeCookie("rememberme");
        onDisconnected();
        flash.success("secure.logout");
        Application.index();
    }
}